﻿using System;
using System.Web.Security;
using System.Collections.Specialized;
using System.Configuration;
using System.Web.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Security.Cryptography;
using System.Text;

namespace Provider
{
    public class CustomMembershipProvider : MembershipProvider
    {
        private string connectionString;
        private int minRequiredPasswordLength = 6;
        public override void Initialize(string name, NameValueCollection config)
        {
            if (config == null)
                throw new ArgumentNullException("config");
            if (String.IsNullOrEmpty(name))
                name = "CustomMembershipProvider";
            config["description"] = "CustomMembershipProvider";
            if (string.IsNullOrEmpty(config["connectionStringName"]))
                throw new Exception("CustomMembershipProvider can not find 'connectionStringName' in provider configuration");
            ConnectionStringsSection connectionStringsSection = (ConnectionStringsSection)WebConfigurationManager.GetSection("connectionStrings");
            connectionString = connectionStringsSection.ConnectionStrings[config["connectionStringName"]].ConnectionString;
            base.Initialize(name, config);
        }

        public override bool ValidateUser(string username, string password)
        {
            bool result = false;
            if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
                return result;
            try
            {
                using (SqlCommand command = new SqlCommand("SELECT COUNT(*) FROM Security.[User] WHERE (UserName = @UserName) AND (Password = @Password) AND (IsActive = 1)", new SqlConnection(connectionString)))
                {
                    command.Parameters.Add("UserName", SqlDbType.NVarChar).Value = ValidateParameter("UserName", username, true);
                    //TODO :
                    //command.Parameters.Add("Password", SqlDbType.NVarChar).Value = ValidateParameter("Password_nvc", EncryptedString(password), true);
                    command.Parameters.Add("Password", SqlDbType.NVarChar).Value = ValidateParameter("Password", password, true);
                    command.Connection.Open();
                    result = Convert.ToBoolean(command.ExecuteScalar());
                    command.Connection.Close();
                }
            }
            catch { }
            return result;
        }

        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            MembershipUser result = null;
            if (String.IsNullOrEmpty(username))
                return null;
            try
            {
                using (SqlCommand command = new SqlCommand("SELECT UserName FROM Security.[User] WHERE (UserName = @UserName)", new SqlConnection(connectionString)))
                {
                    command.Parameters.Add("UserName", SqlDbType.NVarChar).Value = ValidateParameter("UserName", username.ToLower(), true);
                    command.Connection.Open();
                    SqlDataReader reader = command.ExecuteReader();
                    if (reader.Read())
                        result = new MembershipUser(base.Name, Convert.ToString(reader["UserName"]), null, string.Empty, string.Empty, string.Empty, true, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue);
                    command.Connection.Close();
                    return result;
                }
            }
            catch { }
            return null;
        }
        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            if (String.IsNullOrEmpty(username))
                return false;
            try
            {
                using (SqlCommand command = new SqlCommand("Update Security.[User] Set Password = @newPassword WHERE (UserName = @UserName) and (Password = @oldPassword)", new SqlConnection(connectionString)))
                {
                    command.Parameters.Add("UserName", SqlDbType.NVarChar).Value = ValidateParameter("UserName", username.ToLower(), true);
                    command.Parameters.Add("oldPassword", SqlDbType.NVarChar).Value = ValidateParameter("oldPassword", oldPassword, true);
                    command.Parameters.Add("newPassword", SqlDbType.NVarChar).Value = ValidateParameter("newPassword", newPassword, true);
                    command.Connection.Open();
                    int result = command.ExecuteNonQuery();
                    command.Connection.Close();
                    return result > 0;
                }
            }
            catch { }
            return false;
        }
        public override int MinRequiredPasswordLength
        {
            get { return minRequiredPasswordLength; }
        }
        private string EncryptedString(string encryptionValue)
        {
            MD5 encryptor = new MD5CryptoServiceProvider();
            return Convert.ToBase64String(encryptor.ComputeHash(Encoding.Unicode.GetBytes(encryptionValue)));
        }
        private static object ValidateParameter(string ParameterName, object Value, bool IsNullable)
        {
            if (Value == null && !IsNullable)
                throw new ArgumentNullException(ParameterName);
            return (Value == null ? DBNull.Value : Value);
        }
        #region Not Implemented Members
        public override string ApplicationName
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }

        public override bool EnablePasswordReset
        {
            get { throw new NotSupportedException(); }
        }

        public override bool EnablePasswordRetrieval
        {
            get { throw new NotSupportedException(); }
        }

        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotSupportedException(); }
        }

        public override int MinRequiredNonAlphanumericCharacters
        {
            get { return 0; }
        }       

        public override int PasswordAttemptWindow
        {
            get { throw new NotSupportedException(); }
        }

        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotSupportedException(); }
        }

        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotSupportedException(); }
        }

        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotSupportedException(); }
        }

        public override bool RequiresUniqueEmail
        {
            get { throw new NotSupportedException(); }
        }

        public override int GetNumberOfUsersOnline()
        {
            throw new NotSupportedException();
        }

        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotSupportedException();
        }

        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotSupportedException();
        }

        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotSupportedException();
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }

        public override string GetPassword(string username, string answer)
        {
            throw new NotSupportedException();
        }

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            throw new NotSupportedException();
        }

        public override string GetUserNameByEmail(string email)
        {
            throw new NotSupportedException();
        }

        public override string ResetPassword(string username, string answer)
        {
            throw new NotSupportedException();
        }

        public override bool UnlockUser(string userName)
        {
            throw new NotSupportedException();
        }

        public override void UpdateUser(MembershipUser user)
        {
            throw new NotSupportedException();
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            throw new NotSupportedException();
        }
        #endregion
    }
}